#coding=utf-8

#  v1 年份
#  v2 流动资产 1
#  v3 总资产 1
#  v4 流动负债 1
#  v5 总负债 1
#  v6 盈余公积 1
#  v7 未分配利润 1
#  v8 营业收入 2
#  v9 折旧 3
#  v10 利息 2
#  v11 财务费用 2
#  v12 利润总额 2
#  v13 净利润 2
#  v14 股票总量
#  v15 股票收盘价(计算股票市值)

import requests
from bs4 import BeautifulSoup
import re
import numpy as np
from matplotlib import pyplot as plt
import openpyxl


plt.rcParams['font.family'] = ['Arial Unicode MS'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号

DOWNLOAD_URL = 'http://quotes.money.163.com/f10/{0}_{1}.html?type=year'
MV_DOWNLOAD_URL = 'http://quotes.money.163.com/trade/lsjysj_{0}.html?year={1}&season=4'
STOCK_DOWNLOAD_URL ='http://quotes.money.163.com/1{0}.html#01a01'

def download_page(url):
  headers = {
      'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'
  }
  data = requests.get(url, headers=headers).content
  return data

def parse_html(html):
  soup = BeautifulSoup(html)
  table_soup = soup.find('table', attrs={'class': 'table_bg001 border_box limit_sale scr_table'})
  detail_soup = table_soup.find('tbody')
  return detail_soup

def zcfzb_query(html):
  detail_soup = parse_html(html)
  v1 = [child.getText() for child in detail_soup.find_all('tr')[0].contents ]
  v1 = v1_processing(v1)
  v2 = [child.getText() for child in detail_soup.find_all('tr')[27].contents ]
  v2 = data_processing(v2)
  v3 = [child.getText() for child in detail_soup.find_all('tr')[55].contents ]
  v3 = data_processing(v3)
  v4 = [child.getText() for child in detail_soup.find_all('tr')[89].contents ]
  v4 = data_processing(v4)
  v5 = [child.getText() for child in detail_soup.find_all('tr')[100].contents ]
  v5 = data_processing(v5)
  v6 = [child.getText() for child in detail_soup.find_all('tr')[106].contents ]
  v6 = data_processing(v6)
  v7 = [child.getText() for child in detail_soup.find_all('tr')[109].contents ]
  v7 = data_processing(v7)
  return v1, v2, v3, v4, v5, v6, v7

def lrb_query(html):
  detail_soup = parse_html(html)
  v8 = [child.getText() for child in detail_soup.find_all('tr')[1].contents ]
  v8 = data_processing(v8)
  v10 = [child.getText() for child in detail_soup.find_all('tr')[10].contents ]
  v10 = data_processing(v10)
  v11 = [child.getText() for child in detail_soup.find_all('tr')[23].contents ]
  v11 = data_processing(v11)
  v12 = [child.getText() for child in detail_soup.find_all('tr')[37].contents ]
  v12 = data_processing(v12)
  v13 = [child.getText() for child in detail_soup.find_all('tr')[40].contents ]
  v13 = data_processing(v13)
  return v8, v10, v11, v12, v13

def xjllb_query(html):
  detail_soup = parse_html(html)
  v9 = [child.getText() for child in detail_soup.find_all('tr')[68].contents ]
  v9 = data_processing(v9)
  return v9

def capital_stock(code):
  url = STOCK_DOWNLOAD_URL.format(code)
  html = download_page(url)
  soup = BeautifulSoup(html)
  table_soup = soup.find('div', attrs={'class': 'corp_info inner_box'})
  v14 = float(table_soup.find_all('p')[9].getText().split('：', 1)[1].strip().split(' ',1)[0].replace(',',''))
  return v14

def v1_processing(v1):
  re = []
  for data in v1:
    re.append(data.split('-')[0])
  return re

def total_mv(v1, code):
  v15 = []
  for year in v1:
    url = MV_DOWNLOAD_URL.format(code, year)
    html = download_page(url)
    soup = BeautifulSoup(html)
    table_soup = soup.find('table', attrs={'class': 'table_bg001 border_box limit_sale'})
    v15.append(table_soup.find('tbody').find_all('tr')[0].find_all('td')[4].getText())
    v15 = list(map(float,v15))
  return v15

def data_processing(v):
  re = []
  for data in v:
    if data == '--':
      data = '0'
    re.append(data.replace(',', ''))
  re = list(map(float, re))
  return re

def Zscore(x1,x2,x3,x4,x5,x6,x7,x8,x11,x12,x14,x15):

  z1 = [(x2-x4)/x3 for x2, x3, x4 in zip(x2, x3, x4)]
  z2 = [(x6+x7)/x3 for x6, x7 ,x3 in zip(x6, x7, x3)]
  z3 = [(x11+x12)/x3 for x11, x12 ,x3 in zip(x11, x12, x3)]
  z4 = [x14*x15/x5 for x15 ,x5 in zip(x15, x5)]
  z5 = [x8/x3 for x8 ,x3 in zip(x8, x3)]

  Z = [1.2*z1+1.4*z2+3.3*z3+0.6*z4+0.999*z5 for z1,z2,z3,z4,z5 in zip(z1,z2,z3,z4,z5)]

  print("年份","x1","x2","x3","x4","x5","Z-score")
  showResults(x1,z1,z2,z3,z4,z5,Z)
  write2xlsm(x1,z1,z2,z3,z4,z5,Z,'Z-score')
  write2txt(x1,z1,z2,z3,z4,z5,Z,'Z-score')

  x = list(reversed(x1))
  y = list(reversed(Z))
  draw_Zscore_figure(x,y)

def showResults(year,x1,x2,x3,x4,x5,score):
  for year,x1,x2,x3,x4,x5,score in zip(year,x1,x2,x3,x4,x5,score):
    print(year,x1,x2,x3,x4,x5,score)

def draw_Zscore_figure(x,y):
  plt.figure()
  # plt.ylim(0,3.5)
  plt.plot(x,y,'ko-')
  plt.ylabel("Z-SCORE")
  plt.axhline(y = 2.99, ls = ':', c = "gray")
  plt.axhline(y = 1.8, ls = ':', c = "red")
  plt.text(2007,1.65,"破产预警线（1.80）")
  plt.text(2007,3.1,"灰色预警线（2.99）")
  plt.show()


def Fscore(x1,x2,x3,x4,x5,x6,x7,x9,x10,x13,x14,x15):
  f1 = [(x2-x4)/x3 for x2, x3, x4 in zip(x2, x3, x4)]
  f2 = [(x6+x7)/x3 for x6, x7 ,x3 in zip(x6, x7, x3)]
  avg_x5 = [(x5[i]+x5[i-1])/2 for i in range(1, len(x5))] #平均总负债
  f3 = [(x13+x9)/avg_x5 for x13, x9 ,avg_x5 in zip(x13, x9, avg_x5)]
  f4 = [x14*x15/x5 for x15 ,x5 in zip(x15, x5)]
  avg_x3 = [(x3[i]+x3[i-1])/2 for i in range(1, len(x3))] #平均总资产
  f5 = [(x9+x10+x13)/avg_x3 for x9, x10, x13, avg_x3 in zip(x9, x10, x13, avg_x3)]

  F = [-0.1774+1.1091*f1+0.1074*f2+1.9271*f3+0.0302*f4+0.4961*f5 for f1,f2,f3,f4,f5 in zip(f1,f2,f3,f4,f5)]

  print("年份","x1","x2","x3","x4","x5","F-score")
  showResults(x1,f1,f2,f3,f4,f5,F)
  write2xlsm(x1,f1,f2,f3,f4,f5,F,'F-score')
  write2txt(x1,f1,f2,f3,f4,f5,F,'F-score')

  x = list(reversed(x1))
  x.pop(0)
  y = list(reversed(F))

  draw_Fscore_figure(x,y)


def draw_Fscore_figure(x,y):
  plt.figure()
  plt.plot(x,y,'ko-')
  # plt.ylim(-1,1)
  plt.ylabel("F-SCORE")
  plt.text(2007,0.13,"灰色预警线（-0.0501）")
  plt.text(2007,-0.18,"破产预警线（0.1049）")
  plt.axhline(y = 0.1049, ls = ':', c = "gray")
  plt.axhline(y = -0.0501, ls = ':', c = "red")
  plt.show()

def write2xlsm(year,x1,x2,x3,x4,x5,score,des):
  wb = openpyxl.Workbook()
  ws = wb.create_sheet('score',0)
  ws = wb['score']
  ws.append(['年份','x1','x2','x3','x4','x5',des])
  s = [year,x1,x2,x3,x4,x5,score]
  for i in zip(*s):
    ws.append(i)
  name = des + '.xlsx'
  wb.save(name)
  print("打印成功")

def write2txt(year,x1,x2,x3,x4,x5,score,des):
  s = [year,x1,x2,x3,x4,x5,score]
  name = des + '.txt'
  output = open(name,'w',encoding='gbk')
  output.write('year,x1,x2,x3,x4,x5,')
  output.write(des)
  output.write('\n')
  for i in zip(*s):
    for value in i:
      output.write(str(value))
      output.write(',')
    output.write('\n')
  output.close()

def main():
  code = input("请输入公司代码：(例:000001.SZ):")
  code = code.split('.')[0]
  table = ['zcfzb', 'lrb', 'xjllb']

  url = DOWNLOAD_URL.format(table[0], code)
  html = download_page(url)
  v1, v2, v3, v4, v5, v6, v7 = zcfzb_query(html)

  url = DOWNLOAD_URL.format(table[1], code)
  html = download_page(url)
  v8, v10, v11, v12, v13 = lrb_query(html)

  url = DOWNLOAD_URL.format(table[2], code)
  html = download_page(url)
  v9 = xjllb_query(html)

  v14 = capital_stock(code)

  v15 = total_mv(v1, code)

  ZorF = input("请选择需要计算的值('Z' 或者 'F'):")
  if ZorF == 'Z' :
    Zscore(v1,v2,v3,v4,v5,v6,v7,v8,v11,v12,v14,v15)
  else:
    Fscore(v1,v2,v3,v4,v5,v6,v7,v9,v10,v13,v14,v15)
  return

if __name__ == '__main__':
    main()

